#include <windows.h>
#include <iostream>

void SendBKey()
{
    INPUT input = {0};
    input.type = INPUT_KEYBOARD;
    input.ki.wVk = 'B';
    SendInput(1, &input, sizeof(INPUT));
    // 发送键盘释放事件
    input.ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(1, &input, sizeof(INPUT));
}

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HC_ACTION)
    {
        KBDLLHOOKSTRUCT *pKeyBoard = (KBDLLHOOKSTRUCT *)lParam;
        switch (wParam)
        {
        case WM_KEYDOWN:
        case WM_SYSKEYDOWN:
            if (pKeyBoard->vkCode == 'A' || pKeyBoard->vkCode == 'a')
            {
                // 阻止'A'键的实际事件，并发送'B'键的输入事件
                SendBKey();
                return 1;
            }
            break;
        case WM_XBUTTONDOWN: // 鼠标侧键按下事件
        case WM_XBUTTONUP:   // 鼠标侧键释放事件
        // lParam 的低16位包含额外的鼠标信息，高16位包含哪个侧键被按下
            // XBUTTON1 对应于侧键1，XBUTTON2 对应于侧键2
            WORD mouseData = GET_XBUTTON_WPARAM(wParam);

            std::cerr << mouseData << std::endl;
            if (mouseData & XBUTTON1)
            {
                // 侧键1被按下
                if (wParam == WM_XBUTTONDOWN)
                {
                    // 发送"A"键的按下事件
                    SendBKey();
                }
                else if (wParam == WM_XBUTTONUP)
                {
                    // 发送"A"键的释放事件
                    SendBKey();
                }
            }
            break;
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

int main()
{
    // 安装钩子并处理消息...（省略了其他代码）

    HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
    if (hHook == NULL)
    {
        std::cerr << "Hook installation failed!" << std::endl;
        return 1;
    }
    HHOOK hHookM = SetWindowsHookEx(WH_MOUSE_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
    if (hHookM == NULL)
    {
        std::cerr << "Hook installation failed!" << std::endl;
        return 1;
    }

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    UnhookWindowsHookEx(hHook);
    UnhookWindowsHookEx(hHookM);
}